package com.summer.filesync;

import com.summer.filesync.api.ApiServer;
import com.summer.filesync.config.ConfigManager;
import com.summer.filesync.config.SystemConfig;
import com.summer.filesync.database.DatabaseManager;
import com.summer.filesync.network.NetworkManager;
import com.summer.filesync.sync.FileWatcher;
import com.summer.filesync.util.Logger;

/** 分布式文件同步系统主程序 程序入口和核心组件初始化 */
public class Main {

  private static final Logger logger = Logger.getLogger(Main.class);
  private static volatile boolean running = true;

  public static void main(String[] args) {
    logger.info("Starting Distributed File Sync System...");

    try {
      // 初始化系统
      initializeSystem();

      // 启动服务
      startServices();

      // 注册关闭钩子
      registerShutdownHook();

      logger.info("System started successfully");

      // 主循环
      mainLoop();

    } catch (Exception e) {
      logger.error("Failed to start system", e);
      System.exit(1);
    }
  }

  /** 初始化系统 */
  private static void initializeSystem() throws Exception {
    logger.info("Initializing system components...");

    // 初始化配置管理器
    ConfigManager configManager = ConfigManager.getInstance();
    try {
      configManager.loadConfig();
    } catch (Exception e) {
      logger.warn("Failed to load config file, using defaults", e);
    }

    // 设置日志配置
    setupLogging(configManager);

    // 初始化数据库
    DatabaseManager databaseManager = DatabaseManager.getInstance();
    databaseManager.initialize();

    logger.info("System components initialized successfully");
  }

  /** 设置日志配置 */
  private static void setupLogging(ConfigManager configManager) {
    // 设置日志级别
    String logLevel =
        configManager.getProperty(SystemConfig.LOG_LEVEL, SystemConfig.Defaults.LOG_LEVEL);
    try {
      Logger.LogLevel level = Logger.LogLevel.valueOf(logLevel.toUpperCase());
      Logger.setLevel(level);
    } catch (IllegalArgumentException e) {
      logger.warn("Invalid log level: " + logLevel + ", using INFO");
      Logger.setLevel(Logger.LogLevel.INFO);
    }

    // 设置文件日志
    boolean fileLoggingEnabled =
        configManager.getBooleanProperty(
            SystemConfig.LOG_FILE_ENABLED, SystemConfig.Defaults.LOG_FILE_ENABLED);
    if (fileLoggingEnabled) {
      String logFilePath =
          configManager.getProperty(
              SystemConfig.LOG_FILE_PATH, SystemConfig.Defaults.LOG_FILE_PATH);
      Logger.enableFileLogging(logFilePath);
    }
  }

  /** 启动服务 */
  private static void startServices() throws Exception {
    logger.info("Starting services...");

    ConfigManager configManager = ConfigManager.getInstance();

    // 打印系统信息
    printSystemInfo(configManager);

    // 启动网络服务
    try {
      NetworkManager networkManager = NetworkManager.getInstance();
      networkManager.start();
      logger.info("Network service started");
    } catch (Exception e) {
      logger.error("Failed to start network service", e);
      throw e;
    }

    // 启动文件监控服务
    FileWatcher fileWatcher = null;
    try {
      fileWatcher = new FileWatcher();
      Thread watcherThread = new Thread(fileWatcher, "FileWatcher");
      watcherThread.setDaemon(false);
      watcherThread.start();
      logger.info("File watcher started");
    } catch (Exception e) {
      logger.error("Failed to start file watcher", e);
      // 文件监控失败不影响网络功能，记录警告继续运行
      logger.warn("System will continue without file monitoring");
    }

    // 启动API服务器
    try {
      ApiServer apiServer = new ApiServer();
      if (fileWatcher != null) {
        apiServer.setFileWatcher(fileWatcher);
      }
      apiServer.start();
      logger.info("API server started on port " + apiServer.getApiPort());
    } catch (Exception e) {
      logger.error("Failed to start API server", e);
      logger.warn("System will continue without API server");
    }

    logger.info("Services started successfully");
  }

  /** 打印系统信息 */
  private static void printSystemInfo(ConfigManager configManager) {
    String nodeId = configManager.getProperty(SystemConfig.NODE_ID, "");
    String nodeName =
        configManager.getProperty(SystemConfig.NODE_NAME, SystemConfig.Defaults.NODE_NAME);
    String version =
        configManager.getProperty(SystemConfig.NODE_VERSION, SystemConfig.Defaults.NODE_VERSION);
    int port =
        configManager.getIntProperty(SystemConfig.NETWORK_PORT, SystemConfig.Defaults.NETWORK_PORT);

    logger.info("=== System Information ===");
    logger.info("Node ID: " + nodeId);
    logger.info("Node Name: " + nodeName);
    logger.info("Version: " + version);
    logger.info("Port: " + port);
    logger.info("Database: " + DatabaseManager.getInstance().getDatabasePath());
    logger.info("==========================");
  }

  /** 注册关闭钩子 */
  private static void registerShutdownHook() {
    Runtime.getRuntime()
        .addShutdownHook(
            new Thread(
                () -> {
                  logger.info("Shutdown signal received, stopping system...");
                  running = false;
                  shutdown();
                }));
  }

  /** 主循环 */
  private static void mainLoop() {
    while (running) {
      try {
        // 主循环逻辑
        Thread.sleep(1000);

        // TODO: 添加定期任务
        // - 检查网络连接状态
        // - 执行定期同步
        // - 清理过期日志

      } catch (InterruptedException e) {
        logger.info("Main loop interrupted");
        break;
      } catch (Exception e) {
        logger.error("Error in main loop", e);
      }
    }
  }

  /** 关闭系统 */
  private static void shutdown() {
    try {
      logger.info("Shutting down system components...");

      // 关闭网络服务
      try {
        NetworkManager.getInstance().shutdown();
        logger.info("Network service shutdown");
      } catch (Exception e) {
        logger.error("Error shutting down network service", e);
      }

      // 关闭数据库连接
      DatabaseManager.getInstance().close();

      // 保存配置
      try {
        ConfigManager.getInstance().saveConfig();
      } catch (Exception e) {
        logger.warn("Failed to save configuration", e);
      }

      logger.info("System shutdown completed");

    } catch (Exception e) {
      logger.error("Error during shutdown", e);
    }
  }

  /** 停止系统 */
  public static void stop() {
    running = false;
  }

  /** 检查系统是否运行中 */
  public static boolean isRunning() {
    return running;
  }
}
